package com.gwl.server.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gwl.server.entity.SysRole;
import com.gwl.server.entity.SysRoleMenu;
import com.gwl.server.entity.SysUserRole;
import com.gwl.server.lang.Const;
import com.gwl.server.lang.Result;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author gwl
 * @since 2022-05-02
 */
@RestController
@RequestMapping("/sys/role")
public class SysRoleController extends BaseController {

    @GetMapping("/info/{id}")
    @PreAuthorize("hasAnyAuthority('sys:role:list')")
    public Result info(@PathVariable("id") Long id){
        SysRole sysRole = sysRoleService.getById(id);

        // 获取角色相关联的菜单id
        List<SysRoleMenu> role_id = sysRoleMenuService.list(new QueryWrapper<SysRoleMenu>().eq("role_id", id));
        List<Long> collect = role_id.stream().map(p -> p.getMenuId()).collect(Collectors.toList());
        sysRole.setMenuIds(collect);

        return Result.succ(sysRole);
    }

    @GetMapping("/list")
    @PreAuthorize("hasAnyAuthority('sys:role:list')")
    public Result list(String name){
        Page<SysRole> pageData = sysRoleService.page(getPage(),
                new QueryWrapper<SysRole>().like(StrUtil.isNotBlank(name), "name", name));
        return Result.succ(pageData);
    }

    @PostMapping("/save")
    @PreAuthorize("hasAnyAuthority('sys:role:save')")
    @Transactional
    public Result save(@Validated @RequestBody SysRole sysRole){
        sysRole.setCreated(LocalDateTime.now());
        sysRole.setStatu(Const.STATUS_OFF);
        sysRoleService.save(sysRole);

        return Result.succ(sysRole);
    }

    @PostMapping("/update")
    @PreAuthorize("hasAnyAuthority('sys:role:update')")
    @Transactional
    public Result info(@Validated @RequestBody SysRole sysRole){

        sysRole.setUpdated(LocalDateTime.now());
        sysRoleService.updateById(sysRole);

        // 更新缓存
        sysUserService.clearUserAuthorityInfoByRoleId(sysRole.getId());

        return Result.succ(sysRole);
    }

    @PostMapping("/delete")
    @PreAuthorize("hasAnyAuthority('sys:role:delete')")
    @Transactional
    public Result info(@RequestBody Long[] roleIds){
        sysRoleService.removeByIds(Arrays.asList(roleIds));
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("role_id", roleIds));
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().in("role_id", roleIds));
        // 缓存同步删除
        Arrays.stream(roleIds).forEach(id -> {
            sysUserService.clearUserAuthorityInfoByRoleId(id);
        });

        return Result.succ("");
    }

    @PostMapping("/perm/{roleId}")
    @PreAuthorize("hasAnyAuthority('sys:role:perm')")
    @Transactional
    public Result info(@PathVariable("roleId") Long roleId, @RequestBody Long[] menuIds){
        ArrayList<SysRoleMenu> sysRoleMenus = new ArrayList<>();
        Arrays.stream(menuIds).forEach(menuId -> {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setMenuId(menuId);
            roleMenu.setRoleId(roleId);
            sysRoleMenus.add(roleMenu);
        });
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id", roleId));
        sysRoleMenuService.saveBatch(sysRoleMenus);
        sysUserService.clearUserAuthorityInfoByRoleId(roleId);
        return Result.succ(menuIds);
    }

}
